/*
 * @Author: wwssaabb
 * @Date: 2021-11-11 11:06:36
 * @LastEditTime: 2021-12-17 12:00:10
 * @FilePath: \handwritten-code\promise\allsettled.js
 */

//promise.allSettled 接收一个promise数组（不是promise对象则视为成功的promise），返回所有结果，不管是成功或失败

// function allSettled(promiseArr) {
//   let res = []
//   return new Promise((resolve) => {
//     if (promiseArr.length === 0) return resolve(res)
//     let count = 0
//     promiseArr.forEach((p, index) => {
//       res[index] = Promise.resolve(p).then(value => {
//         count++
//         res[index] = {
//           status: 'Fulfilled',
//           value
//         }
//         if (count === promiseArr.length) resolve(res)
//       }, reason => {
//         count++
//         res[index] = {
//           status: 'Rejected',
//           reason
//         }
//       })
//     })
//   })
// }

// const allSettled = function (arr) {
//   let result = [],
//     count = 0
//   return new Promise((resolve, reject) => {
//     arr.forEach((p, index) => {
//       result.push(Promise.resolve(p).then(val => {
//         result[index] = val
//         count++
//         if (result.length === arr.length) resolve(result)
//       }, err => {
//         result[index] = err
//         count++
//         if (result.length === arr.length) resolve(result)
//       }))
//     })
//   })
// }

const allSettled = function (arr) {
  return new Promise((resolve, reject) => {
    let res = [],
      count = 0
    const pushSettled = function (val, index, status) {
      res[index] = {
        status,
        [status === 'fulfilled' ? 'value' : 'reason']: val,
      }
      if (++count === arr.length) resolve(res)
    }
    try {
      arr.forEach((p, index) => {
        Promise.resolve(p).then(val => pushSettled(val, index, 'fulfilled'), reason => pushSettled(reason, index, 'rejected'))
      })
    } catch (error) {
      reject(error)
    }
  })
}

const p1 = new Promise((resolve, reject) => setTimeout(() => {
  reject('p1')
}, 1000))
const p2 = new Promise(resolve => setTimeout(() => {
  resolve('p2')
}, 2000))
const p3 = new Promise(resolve => setTimeout(() => {
  resolve('p3')
}, 3000))
const p4 = new Promise(resolve => setTimeout(() => {
  resolve('p4')
}, 4000))
const p5 = new Promise(resolve => setTimeout(() => {
  resolve('p5')
}, 5000))

let p = [p1, p2, p3, p4, p5, 1, 2, false, null];

allSettled(p).then(res => console.log(res))
Promise.allSettled(p).then(res => console.log(res))